﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using TodoMVC.Models.BusinessModels;
using TodoMVC.Models.DBModels;

namespace TodoMVC.DBServices
{
    /// <summary>
    /// 实现基本的底层数据库接口封装
    /// </summary>
    public class TodoMVCDBServices
    {
        private readonly TodoMVCContext _context;
        public TodoMVCDBServices(TodoMVCContext context)
        {
            _context = context;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public async Task<List<TodoItem>> GetTodoItemsAsync(bool containDeleted = false)
        {
            var list = await _context.TodoItems.ToListAsync();
            if (!containDeleted)
            {
                list = list.Where(t => !t.IsDeleted).ToList();
            }
            return list;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<TodoItem> GetTodoItemByIdAsync(long id)
        {
            return await _context.TodoItems.FindAsync(id);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="guid"></param>
        /// <returns></returns>
        public async Task<TodoItem> GetTodoItemByGuidAsync(Guid guid)
        {
            return await _context.TodoItems.FirstOrDefaultAsync(t => t.Guid == guid);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <param name="todoItem"></param>
        /// <returns></returns>
        public async Task<bool> UpdateTodoItemAsync(TodoItem todoItem)
        {
            if (!await ExistTodoItemAsync(todoItem.Id))
            {
                return false;
            }

            try
            {
                _context.TodoItems.Update(todoItem);
                //_context.Entry(todoItem).State = EntityState.Modified;
                await _context.SaveChangesAsync();
                return true;
            }
            catch (DbUpdateConcurrencyException)
            {
                return false;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="todoItem"></param>
        /// <returns></returns>
        public async Task<TodoItem> AddTodoItemAsync(TodoItem todoItem)
        {
            _context.TodoItems.Add(todoItem);
            //_context.Entry(todoItem).State = EntityState.Added;
            await _context.SaveChangesAsync();
            return todoItem;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <param name="isRealDelete"></param>
        /// <returns></returns>
        public async Task<bool> DeleteTodoItemAsync(long id, bool isRealDelete = false)
        {
            if (!await ExistTodoItemAsync(id))
            {
                return false;
            }

            var todoItem = await _context.TodoItems
                .FindAsync(id);

            if (isRealDelete)
            {
                _context.TodoItems.Remove(todoItem);
                //_context.Entry(todoItem).State = EntityState.Deleted;
            }
            else
            {
                todoItem.IsDeleted = true;
                _context.TodoItems.Update(todoItem);
                //_context.Entry(todoItem).State = EntityState.Modified;
            }

            await _context.SaveChangesAsync();
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task<bool> DeleteTodoItemsAsync(List<long> ids, bool isRealDelete = false)
        {
            foreach (var id in ids)
            {
                if (!await ExistTodoItemAsync(id))
                {
                    return false;
                }

                var todoItem = await _context.TodoItems
                    .FindAsync(id);

                if (isRealDelete)
                {
                    _context.TodoItems.Remove(todoItem);
                    //_context.Entry(todoItem).State = EntityState.Deleted;
                }
                else
                {
                    todoItem.IsDeleted = true;
                    _context.TodoItems.Update(todoItem);
                    //_context.Entry(todoItem).State = EntityState.Modified;
                }
            }
            await _context.SaveChangesAsync();
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<bool> ExistTodoItemAsync(long id)
        {
            var result = _context.TodoItems.Any(e => e.Id == id);
            return await Task.FromResult(result);
        }

        
    }
}
